#statistical methods
import math
import decimal

# values is an array of numerical values
# Pre-conditions: values must not be null (division by zero)
def removeNullVal(values):
    results = []
    for value in values:
        if value is not None:
            results.append(value)
    return results

# return the sum of the values in the list  
def sum_(values):
    sum_ = 0;
    values = removeNullVal(values)
    for n in range(0, len(values)):
        if not values[n] == None:
            sum_ = sum_ + float(values[n])
    return sum_

# return the mean of the values in the list  
def mean(values):
    values = removeNullVal(values)
    total = sum_(values)
    average = float(total)/float(len(values))
    return average

# return the standard deviation of the values in the list    
def s_d(values):
    values = removeNullVal(values)
    m = mean(values)
    s = 0
    size = 0
    for n in range(0, len(values)):
        try:
            t = float(str(values[n])) - m
            s = s + t*t
            size = size + 1
        except ValueError:
            print '1 Null Value found'
        except TypeError:
            print '1 Null Value found' 
        
    sd = math.sqrt(s/size)
    return sd

# return the largest number in the list
def maximum(values):
    values = removeNullVal(values)
    max_ = values[0]
    for n in range(1, len(values)):
        if values[n] > max_:
            max_ = values[n]
    return max_

# return the smallest number in the list
def minimum(values):
    values = removeNullVal(values)
    min_ = values[0]
    for n in range(1, len(values)):
        if values[n] < min_:
            min_ = values[n]
    return min_

# return the difference between the max and the min
def range_(values):
    return maximum(values) - minimum(values)

# return the middle number of the list of values
def median(values):
    values = removeNullVal(values)
    values.sort()
    if len(values)%2 == 1:
        return values[len(values)/2]
    else:
        return float(values[len(values)/2 - 1] + values[len(values)/2])/2

# return the number that occurs the most
def mode(values):
    values = removeNullVal(values)
    values.sort()
    max_freq = 0
    freq = 0
    the_mode = values[0]
    current = values[0]
    for value in values:
        if value == current:
            freq = freq + 1
            if freq > max_freq:
                max_freq = freq
                the_mode = value
        else:
            freq = 1
            current = value
    return the_mode

# return the number of results
def count(values):
    return len(values)
